package com.hdmp.mybatis.plugin;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.ResultHandler;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.sql.Statement;
import java.util.Properties;


/**
 * @author BigFan
 * @create 2018/11/14 2:41 PM
 */
@Intercepts({
        @Signature(
                type = StatementHandler.class,
                method = "update",
                args = {Statement.class}
        ),
        @Signature(
                type = StatementHandler.class,
                method = "query",
                args = {Statement.class, ResultHandler.class}
        )
}
)
@Slf4j
public class SqlTrace implements Interceptor {

    private Properties properties;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Long beginTime = System.currentTimeMillis();
        MetaObject metaObject = SystemMetaObject.forObject(invocation.getTarget());
        String sql = (String) metaObject.getValue("delegate.boundSql.sql");
        Object parameter = metaObject.getValue("delegate.boundSql.parameterObject");
        String javaMethod = (String) metaObject.getValue("delegate.mappedStatement.id");
        String sqlCommandType = (String) metaObject
                .getValue("delegate.mappedStatement.sqlCommandType.name");
        //String jdbcUrl = (String) metaObject
        //        .getValue("delegate.mappedStatement.configuration.environment.dataSource.url");
        String jdbcUrl ="";
        //String userName = (String) metaObject
          //      .getValue("delegate.mappedStatement.configuration.environment.dataSource.username");

        String userName ="";
        String tracingLog = String.format(
                "beginTime: %d\nsql: %s\nparameter: %s\njavaMethod: %s\nsqlCommandType: %s\njdbcUrl: %s\nuserName: %s",
                beginTime, sql, JSON.toJSONString(parameter), javaMethod, sqlCommandType, jdbcUrl, userName);

        try {
            return invocation.proceed();

        } catch (InvocationTargetException e) {
            e.printStackTrace();
            throw e;
        } finally {
            tracingLog = String.format("%s\nendTime: %d", tracingLog, System.currentTimeMillis());
            log.info(tracingLog);
            log.info("execute time:" + (System.currentTimeMillis() - beginTime));

        }
    }

    @Override
    public Object plugin(Object target) {

        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        this.properties = properties;

    }
}
